package middleware

import (
	"a-common/auth/loginauth"
	"a-common/config"
	"a-common/constant"
	"a-common/domain/ctx"
	"a-common/myerr"
	"a-common/utils"
	"context"
	"strings"

	"github.com/gofiber/fiber/v2"
)

// AuthHandler 认证处理中间件
func AuthHandler() fiber.Handler {
	return func(c *fiber.Ctx) error {
		path := c.Path()

		conf := config.Config.Server

		var baseUrl = conf.BaseUrl
		var pubList = conf.PubUrl

		isPub := false
		for _, pubPath := range pubList {
			if strings.HasPrefix(path, baseUrl+pubPath) {
				isPub = true
				break
			}
		}
		// 判断是否是白名单接口无需token校验
		if isPub {
			return c.Next()
		}

		// 获取token
		token := c.Get(constant.TOKEN_NAME)
		if token == "" {
			return c.Status(myerr.CODE_401).JSON(myerr.ERR_SYS_401)
		}
		// 校验token合法性
		ip := utils.NewIpUtils().GetIP(c)
		id, name, device, role := loginauth.AuthToken(token, ip)
		if id == 0 {
			return c.Status(myerr.CODE_401).JSON(myerr.ERR_SYS_401)
		}

		// 判断不同设备token只能访问特定的接口
		if device == constant.APP {
			if !strings.HasPrefix(path, baseUrl+"/app/") {
				return c.Status(myerr.CODE_401).JSON(myerr.ERR_SYS_401)
			}
		} else if device == constant.XCX {
			if !strings.HasPrefix(path, baseUrl+"/xcx/") {
				return c.Status(myerr.CODE_401).JSON(myerr.ERR_SYS_401)
			}
		} else if device == constant.PC {
			// 后台token不做限制
		} else {
			// 未知设备标识
			return c.Status(myerr.CODE_401).JSON(myerr.ERR_SYS_401)
		}

		// 在上下文中存储用户信息
		userCtx := c.UserContext()
		userCtx = context.WithValue(userCtx, ctx.UserCtxKey, ctx.UserCtx{
			Uid:     id,
			Account: name,
			Device:  device,
			Role:    role,
		})
		c.SetUserContext(userCtx)
		return c.Next()
	}
}
